/* 
 * File:   Simplex2.h
 * Author: bastian
 *
 * Created on 22 de mayo de 2011, 20:26
 */

#ifndef FRACCIONES_H
#include "Fracciones.h"
#define FRACCIONES_H
#endif

#ifndef MATRICES_H
#include "Matrices.h"
#define MATRICES_H
#endif

#ifndef TABLASIMPLEX_H
#include "TablaSimplex.h"
#define TABLASIMPLEX_H
#endif

#ifndef TPIVOTE_H
#include "TPivote.h"
#define TPIVOTE_H
#endif

TPivote *Primal_AnalizaColP(TablaSimplex *tabla);
TPivote *Primal_AnalizaFilP(TablaSimplex *tabla, int ColumnaPivote);
int Primal_SeleccionarColP(TPivote *elemento);
int Primal_SeleccionarFilP(TPivote *elemento);
Fraccion TX_NuevoElemento(Matriz *m,int i, int j, int FilP, int ColP);
Fraccion TX_NuevoElementoFilP(Matriz *m,int i, int j, int FilP, int ColP);


//------------------------------------------------------------------------------

TPivote *Primal_AnalizaColP(TablaSimplex *tabla){

    int Columnas = tabla->Columnas;
    int Cant_Z = Columnas - 1;
    int Comparacion;
    
    Fraccion *Zetas = tabla->Zj_Cj;
    Fraccion *Menor = &Zetas[0];
    TPivote *ColP = TPivote_new(Cant_Z);
    ColP->menor=Menor;
    
    LimpiarIndices(ColP->indices,Cant_Z);
    ColP->indices[0]=0;
    
    for(int i = 1; i< Cant_Z; i++){
        Comparacion = Fraccion_Menor(Menor,&Zetas[i]);
        
        if(Comparacion==0){
            ColP->repeticiones++;
            ColP->indices[ColP->repeticiones]=i;
        }
        
        else if(Comparacion==2){
            LimpiarIndices(ColP->indices,Cant_Z);
            ColP->repeticiones=0;
            ColP->indices[0]=i;
            ColP->menor=&Zetas[i];
            Menor = &Zetas[i];
        }
    }
    
    return ColP;
}

void Primal_setColP(TablaSimplex *tabla){

    TPivote *Columna = Primal_AnalizaColP(tabla);
    
    if(Columna->repeticiones==0)
        tabla->ColumnaPivotePrimal = Columna->indices[0];
    
    else
        tabla->ColumnaPivotePrimal = Primal_SeleccionarColP(Columna);
    
    //free's
    free(Columna);

}

int Primal_SeleccionarColP(TPivote *elemento){
    
    int opcion;
    
    do{
        printf("\nColumnas a Seleccionar:\n");
        for(int i = 0; i <= elemento->repeticiones; i++){
        printf("\n(%i) columna %i",i+1,(elemento->indices[i])+1);
        }
    
        printf("\nTu Opcion:");
        scanf("%i",&opcion);
    }while(opcion < 1 || opcion > elemento->repeticiones + 1);
    return elemento->indices[opcion-1];
}
//------------------------------------------------------------------------------

TPivote *Primal_AnalizaFilP(TablaSimplex *tabla, int ColumnaPivote){
    
    int Cant_Filas= tabla->Filas-1;
    int j=1,primeravez=0;
    int Cont = 0, Repeticiones=0;
    int Comparacion;
    TPivote *FilaPivote = TPivote_new(Cant_Filas); 
    Matriz *mat = tabla->MatrizAsociada;
    Fraccion Menor,Aux;
    Fraccion *Filas[Cant_Filas];
    Fraccion *Xb = tabla->Xb;
    
        
    LimpiarIndices(FilaPivote->indices,Cant_Filas);
    for(int i = 0; i < Cant_Filas; i++){
        Filas[i]=&mat->elementos[i][ColumnaPivote];
        if(primeravez == 0){
            if(Fraccion_esMayorQueCero(Filas[i])==0 && Fraccion_esMenorQueCero(&Xb[i])!=0){
                Aux = Fraccion_Dividir(&Xb[i],Filas[i]);
                FilaPivote->indices[Repeticiones]=i;
                Menor = Aux;
                primeravez=1;
            
            }
            else j++;
        
        }
    }
    
    
    for(int i = j; i< Cant_Filas; i++){
        
        if(Fraccion_esMayorQueCero(Filas[i])==0 && Fraccion_esMenorQueCero(&Xb[i])!=0){
                        
            Aux = Fraccion_Dividir(&Xb[i],Filas[i]);
            Comparacion = Fraccion_Menor(&Menor,&Aux);
            
            
            if(Comparacion==2){
                Menor = Aux;
                LimpiarIndices(FilaPivote->indices,Cant_Filas);
                Repeticiones = 0;
                FilaPivote->indices[Repeticiones]=i;
                Menor = Aux;
            }
            
            else if(Comparacion == 0){
                Repeticiones ++;
                FilaPivote->indices[Repeticiones]=i;
            }
        }
        else
            Cont++;
    }
    
    if(Cont==Cant_Filas){
        free(FilaPivote);
        return NULL;
    }
    
    else{
        FilaPivote->menor=&Menor;
        FilaPivote->repeticiones=Repeticiones;
        return FilaPivote;
    }
        
    
}

void Primal_setFilP(TablaSimplex *tabla){

    TPivote *Fila = Primal_AnalizaFilP(tabla,tabla->ColumnaPivotePrimal);
    if(Fila){
        if(Fila->repeticiones==0)
            tabla->FilaPivotePrimal = Fila->indices[0];
    
        else
            tabla->FilaPivotePrimal = Primal_SeleccionarFilP(Fila);
    
        //free's
        free(Fila);
    }
   
}

int Primal_SeleccionarFilP(TPivote *elemento){
    
    int opcion;
    
    do{
        printf("\nFilas a Seleccionar:\n");
        for(int i = 0; i <= elemento->repeticiones; i++){
        printf("\n(%i) fila %i",i+1,(elemento->indices[i])+1);
        }
    
        printf("\nTu Opcion:");
        scanf("%i",&opcion);
    }while(opcion < 1 || opcion > elemento->repeticiones + 1);
    return elemento->indices[opcion-1];
}

//------------------------------------------------------------------------------

Fraccion Primal_Impacto(TablaSimplex *tabla){

    
    int FilP = tabla->FilaPivotePrimal;
    int ColP  = tabla->ColumnaPivotePrimal;
    Fraccion Mayor = tabla->Xb[0];
    Fraccion Mul,Div;
    Fraccion Pivote = tabla->MatrizAsociada->elementos[FilP][ColP];
    for(int i = 1; i < tabla->Filas-1; i++){
        if(Fraccion_Menor(&Mayor,&tabla->Xb[i])==1)
            Mayor = tabla->Xb[i];
    
    }
    
    Mul = Fraccion_Multiplicar(&tabla->Zj_Cj[ColP],&Mayor);
    Div = Fraccion_Dividir(&Mul,&Pivote);
    Fraccion_abs(&Div);
    
    return Div;


}